home *** CD-ROM | disk | FTP | other *** search
- //-----------------------------------------------------------------------------
- // File: cfrmwrk.cpp
- //
- // Desc: CDirectInputActionFramework is the outer-most layer of the UI. It
- // contains everything else. Its functionality is provided by one
- // method: ConfigureDevices.
- //
- // InternalConfigureDevices is called by the CDirectInputActionFramework
- // class. This function actually contains the initialization code and
- // the message pump for the UI.
- //
- // Copyright (C) Microsoft Corporation. All Rights Reserved.
- //-----------------------------------------------------------------------------
-
- #include "common.hpp"
-
-
- //QueryInterface
- STDMETHODIMP CDirectInputActionFramework::QueryInterface(REFIID iid, LPVOID* ppv)
- {
- //null the out param
- *ppv = NULL;
-
- if ((iid == IID_IUnknown) || (iid == IID_IDIActionFramework))
- {
- *ppv = this;
- AddRef();
- return S_OK;
- }
-
- return E_NOINTERFACE;
- }
-
-
- //AddRef
- STDMETHODIMP_(ULONG) CDirectInputActionFramework::AddRef()
- {
- return InterlockedIncrement(&m_cRef);
- }
-
-
- //Release
- STDMETHODIMP_(ULONG) CDirectInputActionFramework::Release()
- {
- LONG cRef;
-
- cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0)
- {
- delete this;
- }
-
- return cRef;
- }
-
- // Manages auto loading/unloading WINMM.DLL
- // There will only be one instance of this class: inside InternalConfigureDevicees.
- class CWinMmLoader
- {
- public:
- CWinMmLoader()
- {
- if (!g_hWinMmDLL)
- {
- g_hWinMmDLL = LoadLibrary(_T("WINMM.DLL"));
- if (g_hWinMmDLL)
- {
- *(FARPROC*)(&g_fptimeSetEvent) = GetProcAddress(g_hWinMmDLL, "timeSetEvent");
- }
- }
- }
- ~CWinMmLoader()
- {
- if (g_hWinMmDLL)
- {
- /*
- * Make sure no new callbacks can get scheduled then sleep to
- * allow any pending ones to complete.
- */
- g_fptimeSetEvent = NULL;
- Sleep( 40 );
- FreeLibrary(g_hWinMmDLL);
- g_hWinMmDLL = NULL;
- }
- }
- };
-
-
-
-
- // internal, which api wraps around
- static HRESULT InternalConfigureDevices(LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
- LPDICONFIGUREDEVICESPARAMSW lpdiCDParams,
- DWORD dwFlags,
- LPVOID pvRefData)
- {
-
- CWinMmLoader g_WinMmLoadingHelper; // Automatically call LoadLibrary and FreeLibrary on WINMM.DLL
-
- // check that we're at least 256 colors
- HDC hMemDC = CreateCompatibleDC(NULL);
- if (hMemDC == NULL)
- {
- etrace(_T("Can't get a DC! Exiting.\n"));
- return E_FAIL;
- }
-
- int bpp = GetDeviceCaps(hMemDC, BITSPIXEL);
- DeleteDC(hMemDC);
- if (bpp < 8)
- {
- etrace1(_T("Screen is not at least 8bpp (bpp = %d)\n"), bpp);
- return E_FAIL;
- }
-
- // do it...
- {
- // create the globals
- CUIGlobals uig(
- dwFlags,
- lpdiCDParams->lptszUserNames,
- lpdiCDParams->dwcFormats,
- lpdiCDParams->lprgFormats,
- &(lpdiCDParams->dics),
- lpdiCDParams->lpUnkDDSTarget,
- lpdiCallback,
- pvRefData
- );
- HRESULT hr = uig.GetInitResult();
- if (FAILED(hr))
- {
- etrace(_T("CUIGlobals.Init() failed\n"));
- return hr;
- }
-
- // make sure the flexwnd window class is registered only during possible use
- {
- struct flexwndscope {
- flexwndscope(CUIGlobals &uig) : m_uig(uig) {CFlexWnd::RegisterWndClass(m_uig.GetInstance());}
- ~flexwndscope() {CFlexWnd::UnregisterWndClass(m_uig.GetInstance());}
- CUIGlobals &m_uig;
- } scope(uig);
-
- // create the main window
- CConfigWnd cfgWnd(uig);
- if (!cfgWnd.Create(lpdiCDParams->hwnd))
- {
- etrace(_T("Failed to create main window\n"));
- return E_FAIL;
- }
-
- // Initialize the shared tooltip object.
- RECT rc = {0, 0, 0, 0};
- CFlexWnd::s_ToolTip.Create(cfgWnd.m_hWnd, rc, TRUE);
- if (!CFlexWnd::s_ToolTip.m_hWnd)
- {
- etrace(_T("Failed to create tooltip window\n"));
- return E_FAIL;
- }
- ::ShowWindow(CFlexWnd::s_ToolTip.m_hWnd, SW_HIDE); // Hide window by default
-
- // enter message loop
- MSG msg;
- while (GetMessage(&msg, NULL, 0, 0))
- {
- // If this is a message for the parent window (game window), only dispatch if it's WM_PAINT.
- if (!cfgWnd.InRenderMode() && msg.hwnd == lpdiCDParams->hwnd && msg.message != WM_PAINT)
- continue;
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
-
- CFlexWnd::s_ToolTip.Destroy();
-
- return uig.GetFinalResult();
- }
- }
-
-
- BOOL AreAcForsGood(LPDIACTIONFORMATW lpAcFors, DWORD dwNumAcFors)
- {
- if (lpAcFors == NULL)
- return FALSE;
-
- if (dwNumAcFors < 1)
- return FALSE;
-
- if (lpAcFors->dwNumActions == 0)
- return FALSE;
-
- return TRUE;
- }
-
-
- //ConfigureDevices
- STDMETHODIMP CDirectInputActionFramework::ConfigureDevices(
- LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
- LPDICONFIGUREDEVICESPARAMSW lpdiCDParams,
- DWORD dwFlags,
- LPVOID pvRefData)
- {
- // check parameters
- if (lpdiCDParams == NULL)
- {
- etrace(_T("NULL params structure passed to ConfigureDevices()\n"));
- return E_INVALIDARG;
- }
-
- // save passed params in case we change 'em
- LPDIACTIONFORMATW lpAcFors = lpdiCDParams->lprgFormats;
- DWORD dwNumAcFors = lpdiCDParams->dwcFormats;
-
- HRESULT hr = InternalConfigureDevices(lpdiCallback, lpdiCDParams, dwFlags, pvRefData);
-
- // restore passed params in case changed
- lpdiCDParams->lprgFormats = lpAcFors;
- lpdiCDParams->dwcFormats = dwNumAcFors;
-
-
- if (FAILED(hr))
- etrace1(_T("ConfigureDevices() failed, returning 0x%08x\n"), hr);
-
- return hr;
- }
-
-
- //constructor
- CDirectInputActionFramework::CDirectInputActionFramework()
- {
- //set ref count
- m_cRef = 1;
- }
-
-
- //destructor
- CDirectInputActionFramework::~CDirectInputActionFramework()
- {
- // not necessary to cleanup action format here
- }
-